package com.ctg.itrdc.imageconsole.service.impl;

import java.net.URL;
import java.text.MessageFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;
import javax.ws.rs.client.WebTarget;
import javax.ws.rs.core.Response;

import org.jboss.resteasy.client.jaxrs.ResteasyClientBuilder;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import com.ctg.itrdc.imageconsole.common.util.HttpRequestUtil;
import com.ctg.itrdc.imageconsole.common.util.TimeUtils;
import com.ctg.itrdc.imageconsole.data.dao.IClusterConfigDao;
import com.ctg.itrdc.imageconsole.data.dao.IDockerMicroUserDao;
import com.ctg.itrdc.imageconsole.data.dao.IUserClusterAssignDao;
import com.ctg.itrdc.imageconsole.data.dto.ClusterAssignDTO;
import com.ctg.itrdc.imageconsole.data.dto.image.MicroUserDTO;
import com.ctg.itrdc.imageconsole.data.entity.ClusterConfig;
import com.ctg.itrdc.imageconsole.data.entity.UserClusterAssign;
import com.ctg.itrdc.imageconsole.data.entity.user.DockerMicroUser;
import com.ctg.itrdc.imageconsole.service.IClusterConfigService;
import com.ctg.itrdc.imageconsole.util.SysManagerUtil;
import com.ctg.itrdc.pasp.security.utils.WebUtils;
import com.ctg.itrdc.paspsdk.common.utils.file.PropertiesUtil;
import com.ctg.itrdc.paspsdk.common.utils.json.JSONUtils;
import com.ctg.itrdc.paspsdk.common.utils.type.StringUtils;

@Component("clusterConfigService")
public class ClusterConfigServiceImpl implements IClusterConfigService {

	private Logger logger = LoggerFactory.getLogger(this.getClass());

	@Resource
	private IClusterConfigDao clusterConfigDao;
	@Resource
	private IUserClusterAssignDao clusterShareDao;
	@Resource
	private IDockerMicroUserDao microUserDao;

	@Override
	public List<ClusterConfig> queryClusterList() {
		Long userId = WebUtils.getCtgUser().getSysUserId();
		List<ClusterConfig> clusterConfigs = clusterConfigDao.jdbcFindList(userId, SysManagerUtil.isRoleOfDockerManager());

		for (ClusterConfig clusterConfig : clusterConfigs) {
			// TODO 这里是由于前端那边的要求：要求后端接收与返回都是以时间撮的形式。有问题联系前端
			if (StringUtils.isNotEmpty(clusterConfig.getCreateTime())) {
				Long time = TimeUtils.parse(clusterConfig.getCreateTime()).getTime();
				clusterConfig.setCreateTime(time.toString());
			}
		}
		return clusterConfigs;
	}

	
	@Override
	public String addCluster(ClusterConfig clusterConfig) {
		// 首先判断集群代码是否已经存在
		boolean flag = checkCodeIsExist(clusterConfig.getId(), clusterConfig.getClusterCode());
		if (flag) {
			return "该集群代码已经存在!";
		}
		// 判断url是否有效
		String apiServerUrl = getApiServerUrl(clusterConfig.getMonitorUrl(), clusterConfig.getClusterCode());
		if (apiServerUrl == null) {
			return "该DashBoard 地址为无效 URL!";
		}
		if (!checkDistributedWebUrl(clusterConfig.getDistributedWebUrl())) {
			return "该分布式web地址为无效地址!";
		}
		clusterConfig.setApiServerUrl(apiServerUrl);
		long id = 0;
		if (null == clusterConfig.getId()) {
			clusterConfig.setCreateTime(TimeUtils.getNowDateStr());
			clusterConfig.setCreateUserId(WebUtils.getCtgUser().getSysUserId());
			id = clusterConfigDao.insert(clusterConfig);
		} else {
			clusterConfig.setCreateTime(TimeUtils.getNowDateStr());
			clusterConfig.setCreateUserId(WebUtils.getCtgUser().getSysUserId());
			id = clusterConfigDao.updateByPrimaryKey(clusterConfig);
		}
		if (id > 0) {
			return null;
		} else {
			return "数据保存失败！";
		}
	}
	
	public boolean checkDistributedWebUrl(String distributedWebUrl) {
		try {
			String urlString = String.format("http://%s/ctg-dwf-admin/conf/clusters", distributedWebUrl);
			WebTarget target = new ResteasyClientBuilder().build().target(urlString);
			target.queryParam("ctype", "tengine").queryParam("limit", 1)
					.queryParam("offset", 1).request().get();
			return true;
		} catch (Exception e) {
			logger.error("验证分布式web地址时异常,基本断定是用户所配置的分布式web地址无效！", e);
			return false;
		}
		
	}

	public Boolean checkCodeIsExist(Long id, String clusterCode) {
		long userId = WebUtils.getCtgUser().getSysUserId();
		List<ClusterConfig> list = clusterConfigDao.findByClusterCode(id, clusterCode, userId);

		if (list != null && list.size() > 0) {
			return true;
		} else {
			return false;
		}
	}

//	public Boolean checkUrlIsExist(String monitorUrl) {
//		List<ClusterConfig> list = clusterConfigDao.findByMonitorUrl(monitorUrl);
//
//		if (list != null && list.size() > 0) {
//			return true;
//		} else {
//			return false;
//		}
//	}

	@Override
	public String getApiServerUrl(String monitorUrl, String clusterCode) {
		try {
			String urlString = PropertiesUtil.getConfigValueCache("k8s.properties", "getApiServerUrl.api");
			urlString = MessageFormat.format(urlString, monitorUrl, clusterCode);
			// 创建URL连接
			URL url = new URL(urlString);
			HttpRequestUtil requestUtil = new HttpRequestUtil(url);
			WebTarget target = HttpRequestUtil.target;
			Response response = target.request().get();
			String jsonStr = requestUtil.getResponseJsonData(response);
			return (String) JSONUtils.jsonToMap(jsonStr).get("url");
		} catch (Exception e) {
			logger.error("验证k8s集群配置时的url是否正常时，发生异常！", e);
			return null;
		}
	}

	@Override
	public String queryResourcesByUrls(String clusterCodes) throws Exception {
		Map<String, Object> map = JSONUtils.jsonToMap(clusterCodes);
		String[] codes = ((String) map.get("clusterCodes")).split(",");

		StringBuffer sb = new StringBuffer();
		sb.append("[");
		for (int i = 0, len = codes.length; i < len; i++) {
			ClusterConfig clusterConfig = clusterConfigDao.queryByClusterCode(codes[i]);

			String urlString = PropertiesUtil.getConfigValueCache("k8s.properties", "getClusterResrTotal.api");
			urlString = MessageFormat.format(urlString, clusterConfig.getMonitorUrl());
			// 创建URL连接
			URL url = new URL(urlString);
			HttpRequestUtil requestUtil = new HttpRequestUtil(url);
			WebTarget target = HttpRequestUtil.target;
			Response response = target.request().get();
			String jsonStr = requestUtil.getResponseJsonData(response);
			sb.append(jsonStr);
			if (i != (len - 1)) {
				sb.append(",");
			}
		}
		sb.append("]");

		return sb.toString();
	}

	@Override
	public int deleteByPrimaryKey(ClusterConfig clusterConfig) {
		return clusterConfigDao.deleteByPrimaryKey(clusterConfig);
	}

	@Override
	public List<ClusterConfig> queryByEntity(ClusterConfig entity) {
		return clusterConfigDao.selectByExample(entity);
	}

	@Override
	public ClusterConfig queryCluster(Long id) {
		ClusterConfig clusterConfig = new ClusterConfig();
		clusterConfig.setId(id);
		return clusterConfigDao.selectByPrimaryKey(clusterConfig);
	}

	@Override
	public void clusterAssign(ClusterAssignDTO clusterShareDTO) {
		Long currentUserId = WebUtils.getCtgUser().getSysUserId();
		
		UserClusterAssign clusterShare = new UserClusterAssign();
		clusterShare.setRelateUserId(currentUserId);
		clusterShare.setClusterConfigId(clusterShareDTO.getClusterConfigId());
		// 每次都先删除该集群与所有分配用户、被分配用户之间的关联记录（一般被分配用戶就是管理员，且只有一个）
		clusterShareDao.deleteByClusterConfigIdAndRelateUserId(clusterShareDTO.getClusterConfigId(), currentUserId);
		if (clusterShareDTO.getSysUserIds() == null) {
			return;
		}
		for(Long sysUserId:clusterShareDTO.getSysUserIds()){
			clusterShare.setUserId(sysUserId);
			// 新增该集群与所有分配用户、被分配用户之间的关联记录
			clusterShareDao.insert(clusterShare);
		}
	}

	@Override
	public List<MicroUserDTO> queryAssignUsers(Long clusterConfigId) {
		List<MicroUserDTO> userDTOs = new ArrayList<>();
		Long currentUserId = WebUtils.getCtgUser().getSysUserId();
		
		UserClusterAssign userClusterShare = new UserClusterAssign();
		userClusterShare.setRelateUserId(currentUserId);
		userClusterShare.setClusterConfigId(clusterConfigId);
		
		List<UserClusterAssign> userClusterShares = clusterShareDao.selectByExample(userClusterShare);
		for(UserClusterAssign share : userClusterShares) {
			DockerMicroUser microUser = new DockerMicroUser();
			microUser.setSysUserId(share.getUserId());
			microUser.setAvailable(1);
			microUser = microUserDao.selectByExample(microUser).get(0);
			
			MicroUserDTO microUserDTO = new MicroUserDTO();
			microUserDTO.setCode(microUser.getCode());
			microUserDTO.setName(microUser.getName());
			microUserDTO.setSysUserId(microUser.getSysUserId());
			
			userDTOs.add(microUserDTO);
		}
		
		return userDTOs;
	}

}
